<template>
  <base-modal  
    :class="baseModalClassNames"
    :show.sync="visible" 
    :title="title" 
    width="414px" 
    @close="aiDialogClose"
  >
    <div class="ai-summaries-dialog">
      <div v-if="status === 1" class="ai-summaries-dialog_content">
        <div class="content_field">选择摘要字段</div>
        <el-select v-model="selectTags" multiple placeholder="请选择" filterable class="content_select">
          <el-option v-for="item in aifieldList" :key="item.fieldName" :label="item.displayName" :value="item.fieldName"> </el-option>
        </el-select>
        <!-- <button type="primary" @click="alltags">全选摘要</button> -->
      </div>
      <div v-if="status === 2" class="loading">
        <div>
          <div class="loading_text">小宝正在努力摘要中，请耐心等待...</div>
          <div class="loading_box">
            <el-progress :percentage="percentage" class="loading_progress"></el-progress>
          </div>
          <div 
            v-if="isShowCountDown"
            class="loading_countdown_block"
          >
            <span class="loading_countdown">
              {{ countDownCurrent }}
            </span>
            秒后自动转后台任务
          </div>
        </div>
      </div>
      <div v-if="status === 3" class="text">
        <div class="text_content" v-if="showText">
          <pre v-html="showText">
          </pre>
        </div>
      </div>
    </div>
    <div slot="footer">
      <div v-if="status === 1">
        <el-button type="plain-third" @click="cancel">取消</el-button>
        <el-button type="primary" @click="enterSummaires">摘要一下</el-button>
      </div>
      <div v-if="status === 2">
        <el-button type="plain-third" @click="closeSummaries">结束摘要</el-button>
        <el-button type="primary" @click="minimize">转后台任务</el-button>
      </div>
      <div v-if="status === 3">
        <el-button 
          type="plain-third" 
          @click="visible = false"
        >
          关闭
        </el-button>
        <el-button 
          v-if="isImmediatelyGenerate"
          class="ai-summaries-result-dialog__reopen-btn"
          type="primary" 
          @click="reopen"
        >
          重新摘要
        </el-button>
        <el-button 
          type="primary"
          @click="onGenerateWikiClickHandler"
        >
          生成知识库
        </el-button>
      </div>
    </div>
  </base-modal>
</template>

<script>
/* api */
import { exportSummary } from '@src/api/AIApi'
/* enum */
import StorageKeyEnum from '@model/enum/StorageKeyEnum'
/* hooks */
import { useTenantId, useRootUser } from '@hooks/useRootWindow';
/* util */
import { openTabForWikiCreate } from '@src/util/business/openTab'
import { setClipboardData } from '@src/util/dom'
import { exportAlert, commonAlert, showExportList } from '@src/util/alert';
import { isFalsy } from 'pub-bbx-utils'

export default {
  name: 'AiSummariesDialog',
  props: {
    // 字段列表
    aifieldList: {
      type: Array,
      default: () => [],
    },
    // 当前选中的字段列表数据
    currentFieldList: {
      type: Array,
      default: () => [],
    },
    currentType: {
      type: String,
      default: ''
    },
    systemRobotId: {
      type: [String, Number]
    }
  },
  setup() {
    const tenantId = useTenantId()
    const rootUser = useRootUser()
    return {
      tenantId,
      rootUser
    }
  },
  data() {
    return {
      status: 1, // 弹窗状态三种样式
      visible: false,
      title: 'AI摘要',
      selectTags: [], // 选中的下拉标签
      percentage: 0, // 进度条百分比
      selectFieldType: [], // 选中的字段类型
      selectListTasks: [], // 选中的工单数据
      showText: '', // 显示的文本数据
      controller: null,
      // 倒计时默认值
      countDownDefault: 60,
      // 当前倒计时
      countDownCurrent: 60,
      // 倒计时定时器
      countDownInterval: null,
      // 当前请求参数
      currentRequestParams: null,
      // 是否显示倒计时
      isShowCountDown: false,
      // 是否是当前立即生成的摘要
      isImmediatelyGenerate: false,
    };
  },
  computed: {
    baseModalClassNames() {
      return {
        'ai-summaries-result-dialog': this.isResultStatus && this.showText
      }
    },
    isResultStatus() {
      return this.status === 3;
    }
  },
  methods: {
    // 全选tag 测试
    // alltags() {
    //   this.selectTags = this.aifieldList.map(item => item.fieldName);
    // },
    init() {
      this.status = 1;
      this.selectTags = [];
    },
    open() {
      
      const firstTemplateId = this.currentFieldList[0]?.templateId
      let temp = this.currentFieldList.every((item) => {
        return item.templateId === firstTemplateId
      })
      
      if (!temp) {
        this.$message.warning('请确保选中的数据是相同的工单类型');
        return
      }
      
      this.init();
      this.visible = true;
    },
    cancel() {
      this.visible = false;
      this.selectTags = [];
    },
    /**
     * @desc 结束摘要处理函数
     */
    async closeSummaries() {
      this.visible = false;
      this.status = 1;
      this.selectTags = [];
      this.controller.abort();
    },
    minimize() {
      console.log('最小化');
      const isNotShowMessageTip = true
      this.clearCountDown();
      this.timeoutErrorHandler(isNotShowMessageTip);
    },
    exportSummary(isNotShowMessageTip) {
      
      const params = this.currentRequestParams || {};
      
      exportSummary(params)
        .then(res => {
          
          if(res.succ){
            
            if (isFalsy(isNotShowMessageTip)) {
              exportAlert(res.message);
            } else {
              showExportList();
            }
            
            this.cancel();
            
          } else {
            commonAlert(res.message);
          }
          
        })
        .finally(() => {
          this.exportAllLoading = false;
        })
    },
    /**
     * @desc 确认摘要
     */
    async enterSummaires() {
      
      this.FilterListHandler();
      this.percentage = 0;
      this.status = 2;
      
      const interval = setInterval(() => {
        this.percentage += 2;
        if (this.percentage > 99) {
          this.percentage = 99;
        }
      }, 600);
      
      this.startCountDown()
      
      const params = {
        fields: this.selectFieldType,
        tasks: this.selectListTasks,
        tenantId: this.tenantId,
        userId: this.rootUser?.userId,
        robotId: this.systemRobotId
      };
      const controller = new AbortController();
      
      this.isImmediatelyGenerate = false
      this.currentRequestParams = params;
      this.controller = controller;
      
      try {
        
        const response = await fetch('/language/task/summary', {
          method: 'POST',
          headers: {
            'Content-Type': 'application/json',
          },
          signal: controller.signal,
          body: JSON.stringify(params),
        });
        
        this.clearCountDown()
        
        // 是否是超时错误
        const isTimeoutError = response.status == 504
        if (isTimeoutError) {
          this.timeoutErrorHandler()
          return;
        }
        
        if (!response.ok) {
          this.$message.error('请求失败');
          clearInterval(interval);
          return;
        }
        
        const res = await response.json();
        if (res.status !== 200) {
          return;
        }
        
        clearInterval(interval);
        this.showText = res.data;
        this.percentage = 100;
        this.status = 3;
        this.isImmediatelyGenerate = true
        
      } catch (error) {
        console.error(error);
      }
    },
    /**
     * @desc 重置选择
     */
    resetSelectTaskAndField() {
      this.selectFieldType = []
      this.selectListTasks = []
    },
    /**
     * @desc 过滤数据处理器
     */
    FilterListHandler() {
      this.resetSelectTaskAndField()
      if (this.selectTags.length === 0) {
        this.$message.warning('未选择字段，请选择字段');
        return;
      }
      if (this.selectListTasks.length > 100) {
        this.$message.warning('工单数量不能超过100');
        return;
      }
      this.aifieldList.forEach(item => {
        if (this.selectTags.includes(item.fieldName)) {
          this.selectFieldType.push(item);
        }
      });
      
      this.currentFieldList.forEach(item => {
        
        const task = {};
        
        this.selectTags.forEach(tag => {
          let _tag = this.filterField(tag);
          // 如果需要过滤字段进入筛选，否则不筛选
          if (_tag) {
            // 所有筛选后的值都赋值给value，然后再赋值给task
            let value = null;
            let arrTag = _tag.split('.');
            // 处理数组的我现在只做一层，遍历数组中对应的对象属性值
            let firstFieldValue = item[arrTag[0]];
            let firstField = arrTag[0]
            if (Array.isArray(firstFieldValue) && firstFieldValue.length != 0) {
              let arrTemp = [] // 保存对象上的数组中的数据
              firstFieldValue.forEach((item, index) => {
                arrTemp.push(this.getMultilayerValue(arrTag.slice(1), firstFieldValue[index]));
              })
              // 下面特殊字段中，存在多个数据拼接现象
              if (firstField === 'executorTags') {
                value = arrTemp.join('、')
              }
              if (firstField !== 'executorTags') {
                value = arrTemp.join(', ')
              }
            } else {
              value = this.getMultilayerValue(arrTag, item);
            }
            if (value !== undefined) {
              task[tag] = this.formatNull(value)
            } else {
              task[tag] = this.getAttributeValue(item, _tag);
            }
          } else {
            if (item[tag] !== undefined) {
              task[tag] = this.formatNull(item[tag])
            } else {
              task[tag] = this.getAttributeValue(item, tag);
            }
          }
        });
        
        this.selectListTasks.push(task);
        
      });
    },
    /**
     * @desc 过滤字段属性中数据
     * @param {String} tag 字段属性名
     * @param {Object} item 具有attribute属性的数据源
     * @return {String} 过滤后的字段属性值
     */
    getAttributeValue(item, tag) {
      const attributes = item?.attribute;
      if (attributes && typeof attributes === 'object') {
        let value = '';
        let arrTag = tag.split('.');
        for (let i = 0; i < arrTag.length; i++) {
          if (attributes[arrTag[i]] === null || attributes[arrTag[i]] === undefined) {
            value = '';
            break;
          }
          value = attributes[arrTag[i]]
        }
        return value
      }
    },
    /**
     * @desc 获取多层对象下属性值
     * @param {Array} tag 字段名
     * @param {Object} source 字段属性值
     * @return {String} 过滤后的字段属性值
     *
     * @example
     * getMultilayerValue(['a', 'b'], { a: { b: 1 } }) // 1
     */
    getMultilayerValue(tag, source) {
      let value = source;
      tag.forEach(i => {
        value = value?.[i];
      });
      return value;
    },
    /**
     * @desc 过滤字段
     * @param {String} tag 字段名
     * @return {String} 过滤后的字段名。如果有多层对象调用请用.表示
     */
    filterField(tag) {
      if (tag === 'customer') return 'customerEntity';
      if (tag === 'tlmName') return 'linkMan.name';
      if (tag === 'tlmPhone') return 'linkMan.phone';
      if (tag === 'taddress') return 'address';
      if (tag === 'product') return 'products.name';
      if (tag === 'qualityStartTime') return 'qualityEntity.qualityStartTime';
      if (tag === 'qualityEndTime') return 'qualityEntity.qualityEndTime';
      if (tag === 'qualityStatus') return 'qualityEntity.qualityStatus';
      if (tag === 'createUserName') return 'createUser.displayName';
      if (tag === 'executorName') return 'executorUser.displayName';
      if (tag === 'allotName') return 'allotUser.displayName';
      if (tag === 'synergies') return 'synergies';
      if (tag === 'allotTypeStr') return 'allotType';
      if (tag === 'acceptUsedTimeStr') return 'acceptUsedTime';
      if (tag === 'taskUsedTimeStr') return 'taskUsedTime';
      if (tag === 'workUsedTimeStr') return 'workUsedTime';
      if (tag === 'taskResponseTimeStr') return 'taskResponseTime';
      if (tag === 'serviceproviders') return 'serviceProviderSubForm.providerName';
      if (tag === 'executorTags') return 'executorTags.name'
    },
    /**
     * @desc 格式化null，将null变为空字符串
     * @param {String} value 需要格式化的值
     */
    formatNull(value) {
      if (value === null) {
        return '';
      }
      return value;
    },
    aiDialogClose() {
      this.status = 1;
    },
    reopen() {
      this.status = 1;
      this.selectTags = [];
    },
    /** 
     * @description 生成知识库
    */
    onGenerateWikiClickHandler() {
      // 保存摘要结果到 sessionStorage
      this.saveSummaryResultToSessionStorage()
      // 复制摘要结果到剪切板
      setClipboardData(this.showText)
      // 打开知识库创建页面
      openTabForWikiCreate()
      this.closeSummaries()
    },
    /** 
     * @description 保存摘要结果到 sessionStorage
    */
    saveSummaryResultToSessionStorage() {
      sessionStorage.setItem(StorageKeyEnum.AITaskSummary, this.showText)
    },
    /** 
     * @description 开始倒计时
     * 代码来源：AI自动生成的
    */
    startCountDown() {
      
      // 设置当前倒计时为默认值
      this.countDownCurrent = this.countDownDefault
      // 显示倒计时
      this.isShowCountDown = true
      
      // 开始倒计时定时器
      this.countDownInterval = setInterval(() => {
        
        // 倒计时减一
        this.countDownCurrent--;
        
        // 如果倒计时为0，清除定时器
        if (this.countDownCurrent <= 1) {
          this.clearCountDown()
        }
        
      }, 1000)
      
    },
    /** 
     * @description 清除倒计时
     * 代码来源：AI自动生成的
    */
    clearCountDown() {
      try {
        // 隐藏倒计时
        this.isShowCountDown = false
        // 清除定时器
        clearInterval(this.countDownInterval)
        this.countDownInterval = null
        this.countDownCurrent = this.countDownDefault
      } catch (error) {
        console.error(`清除倒计时失败：${error}`)
      }
    },
    /** 
     * @description 超时错误处理
     * 如果摘要超时，直接执行后台任务导出摘要结果
    */
    timeoutErrorHandler(isNotShowMessageTip = true) {
      this.closeSummaries()
      this.exportSummary(isNotShowMessageTip)
    }
  },
};
</script>
<style lang="scss" scoped>
.ai-summaries-dialog {
  height: 143px;
  width: 100%;
  &_content {
    padding: 24px;
    .content {
      &_field {
        font-weight: 500;
        font-size: 18px;
        margin-bottom: 8px;
        line-height: 26px;
        color: #3d3d3d;
      }
      &_select {
        width: 100%;
      }
    }
  }
  
  .loading_countdown {
    color: $color-danger;
  }
  
}
.loading {
  height: 100%;
  width: 100%;
  padding: 0 24px;
  display: flex;
  flex-direction: column;
  justify-content: center;
  &_text {
    font-weight: 400;
    font-size: 14px;
    line-height: 22px;
    color: #262626;
  }
  &_box {
    padding: 10px 0;
  }
}
.text {
  // width: 100%;
  height: 100%;
  &_content {
    font-size: 14px;
    line-height: 22px;
    font-weight: 400;
    padding: 24px 24px 1px 24px;
  }
}
.loading_countdown_block {
  display: flex;
  justify-content: flex-end;
  padding-right: 12px;
}
</style>

<style lang="scss">
.ai-summaries-result-dialog {
  .base-modal  {
    width: 800px !important;
    height: 600px !important;
  }
  .text_content {
    pre {
      text-wrap: wrap;
    }
  }
}
.export-row-AI_TASK_SUMMARY_EXPORT {
  .export-not-download {
    visibility: hidden;
  }
}
</style>
